﻿Imports System.Reflection

<ComClass(ClsAcadApplication.ClassId, ClsAcadApplication.InterfaceId, ClsAcadApplication.EventsId)>
Public Class ClsAcadApplication

#Region "COM GUID"
    ' 这些 GUID 提供此类的 COM 标识 
    ' 及其 COM 接口。若更改它们，则现有的
    ' 客户端将不再能访问此类。
    Public Const ClassId As String = "20fa8738-a366-4bbe-983f-e4b515cf7039"
    Public Const InterfaceId As String = "8610b3d1-b7a1-4c5d-a575-7e265327a6b0"
    Public Const EventsId As String = "a1e91f78-4a31-4773-a4cb-70c7ba03e9ba"
#End Region

    ' 可创建的 COM 类必须具有一个不带参数的 Public Sub New() 
    ' 否则， 将不会在 
    ' COM 注册表中注册此类，且无法通过
    ' CreateObject 创建此类。
    Public Sub New()
        MyBase.New()
    End Sub

    Private _hwdn As Long
    Public Property HWND() As Long
        Get
            Return _hwdn
        End Get
        Set(ByVal value As Long)
            _hwdn = value
        End Set
    End Property

    Private _ver As String
    Public Property Version() As String
        Get
            Return _ver
        End Get
        Set(ByVal value As String)
            _ver = value
        End Set
    End Property

    Private _caption As String
    Public Property Caption() As String
        Get
            Return _caption
        End Get
        Set(ByVal value As String)
            _caption = value
        End Set
    End Property

    Private _ws As AcWindowState
    Public Property WindowState() As AcWindowState
        Get
            Return _ws
        End Get
        Set(ByVal value As AcWindowState)
            _ws = value
        End Set
    End Property

    Private _visible As Boolean
    Public Property Visible() As Boolean
        Get
            Return _visible
        End Get
        Set(ByVal value As Boolean)
            _visible = value
        End Set
    End Property
    ''' <summary>
    ''' Checks whether AutoCAD is idle and ready to accept automation calls from out-of-process applications. 
    ''' </summary>
    ''' <returns></returns>
    Public ReadOnly Property IsQuiescent() As Boolean
        Get
            Return Me.AcadObject.GetAcadState().IsQuiescent
        End Get
    End Property

    Public ReadOnly Property ActiveDocument() As ClsAcadDocument
        Get
            Dim doc As New ClsAcadDocument
            doc.GetInforFromAcad(Me.AcadObject.ActiveDocument, Me)
            Return doc
        End Get
    End Property

    Public Enum AcWindowState
        acMin = 2 ':  The window Is minimized. 
        acMax = 3 ':  The window Is maximized. 
        acNorm = 1 ': The window Is normal (neither minimized nor maximized). 
    End Enum

    Public AcadObject As Object
    Public Sub GetInforFromAcad(acApp As Object)
        If TypeName(acApp) = "IAcadApplication" Then
            Me.AcadObject = acApp
            Dim t = Me.GetType()
            For Each item As PropertyInfo In t.GetProperties().ToList().Where(Function(c) c.CanWrite).ToList()
                item.SetValue(CType(Me, Object), CallByName(acApp, item.Name, CallType.Get, Nothing), Nothing)
            Next
        End If
    End Sub

    Public Sub ZoomAll()
        Call Me.AcadObject.ZoomAll()
    End Sub
    Public Sub ZoomExtents()
        Call Me.AcadObject.ZoomExtents()
    End Sub
    Public Sub ZoomWindow(LowerLeft As ClsPoint2d, UpperRight As ClsPoint2d)
        Call Me.AcadObject.ZoomWindow(LowerLeft.To3DArray(), UpperRight.To3DArray())
    End Sub

    Public ReadOnly Property Documents As ClsAcadDocument()
        Get
            Dim clsDocs As New List(Of ClsAcadDocument)
            Dim docs = Me.AcadObject.Documents
            For Each item As Object In docs
                Dim doc As New ClsAcadDocument
                doc.GetInforFromAcad(item, Me)
                clsDocs.Add(doc)
            Next
            Return clsDocs.ToArray()
        End Get
    End Property

    Public Function DocumentsObjects() As Object
        Return Me.AcadObject.Documents
    End Function

    ''' <summary>
    ''' Accepts a program ID and attempts to load it into AutoCAD as an in-process server
    ''' </summary>
    ''' <param name="ProgID">The program ID of the interface object to return. </param>
    ''' <returns></returns>
    Public Function GetInterfaceObject(ProgID As String) As Object
        Return Me.AcadObject.GetInterfaceObject(ProgID)
    End Function


End Class


